/**
 * GLOBALS
 */
var hasChanged = false;

/**
 * get_indent
 *
 * given a taxonomy-draggable, return the indent level
 */
function get_indent(element) {
    if (element.hasClass('taxonomy-indent1')) {
        return 1;
    } else if (element.hasClass('taxonomy-indent2')) {
        return 2;
    } else if (element.hasClass('taxonomy-indent3')) {
        return 3;
    } else if (element.hasClass('taxonomy-indent4')) {
        return 4;
    } else if (element.hasClass('taxonomy-indent5')) {
        return 5;
    }
}

/**
 * indent_cascade
 *
 * given a taxonomy-draggable, find first list element and
 * adjust all indent to insure data integrity.
 */
function indent_cascade(elem) {
    element = $(elem);
    previous = element.prev();
    if (previous && previous.get(0) && previous[0].tagName == 'LI') {
        max_indent = get_indent(previous) + 1;
        indent = get_indent(element);
        if (indent > max_indent) {
            element.removeClass('taxonomy-indent'+indent);
            element.addClass('taxonomy-indent'+max_indent);
        }
    } else {
        indent = get_indent(element);
        element.removeClass('taxonomy-indent'+indent);
        element.addClass('taxonomy-indent1');
    }
    next = element.next();
    if (next && next.get(0) && next[0].tagName == 'LI') {
        indent_cascade(next[0]);
    }
}

/**
 * jQuery ready function
 */
$(document).ready(function() {
    // extends jquery with the disableTextSelect function
    $.extend($.fn.disableTextSelect = function() {
        return this.each(function(){
            if ($.browser.mozilla) {
                $(this).css('MozUserSelect', 'none');
            } else if ($.browser.msie) {
                $(this).bind('selectstart', function() {return false;});
            }
        });
    });
    // some variables used for drag & drop.
    var draggable = null;
    var dxoffset = 0;
    var dyoffset = 0;
    // MOUSEDOWN - catch draggable
    $('.taxonomy-draggable').mousedown(function(evt) {
        draggable = $(this);
        draggable.addClass('taxonomy-dragging');
        dxoffset = evt.pageX - draggable.position().left;
        dyoffset = evt.pageY - draggable.position().top;
        document.body.style.cursor = "move";
    }).disableTextSelect();
    // MOUSEUP - release draggable, if any
    $(document).mouseup(function(evt) {
        if (draggable) {
            // get first element of list.
            ul = draggable.parent();
            elem = ul.children()[0];
            indent_cascade(elem);
            draggable.removeClass('taxonomy-dragging');
            draggable = null;
            document.body.style.cursor = "auto";
        }
    });
    // MOUSEMOVE - move draggable around, if any
    $(document).mousemove(function(evt) {
        if (draggable) {
            // Check Y Offset
            yPos = draggable.position().top + dyoffset;
            offset = evt.pageY - yPos;
            if (offset > draggable.height()) {
                next = draggable.next();
                if (next && next.get(0) && next[0].tagName == 'LI') {
                    clone = draggable.clone();
                    clone.mousedown(function (evt) {draggable = $(this);});
                    clone.disableTextSelect();
                    next.after(clone);
                    draggable.remove();
                    draggable = clone;
                    hasChanged = true;
                }
            } else if (offset < -draggable.height()) {
                previous = draggable.prev();
                if (previous && previous.get(0) && previous[0].tagName == 'LI') {
                    clone = draggable.clone();
                    clone.mousedown(function (evt) {draggable = $(this);});
                    clone.disableTextSelect();
                    previous.before(clone);
                    draggable.remove();
                    draggable = clone;
                    hasChanged = true;
                }
            } else {
                // Check X Offset (Priority is given to Y Offset!)
                previous = draggable.prev();
                if (previous && previous.get(0) && previous[0].tagName == 'LI') {
                    max_indent = get_indent(previous) + 1;
                    current_indent = get_indent(draggable);
                    xPos = draggable.position().left + dxoffset;
                    offset = evt.pageX - xPos;
                    if (offset > 20) {
                        if (current_indent < max_indent) {
                            before = 'taxonomy-indent'+current_indent;
                            after = 'taxonomy-indent'+(current_indent+1);
                            draggable.removeClass(before);
                            draggable.addClass(after);
                            dxoffset = evt.pageX - draggable.position().left;
                            hasChanged = true;
                        }
                    } else if (offset < -20) {
                        if (current_indent > 1) {
                            before = 'taxonomy-indent'+current_indent;
                            after = 'taxonomy-indent'+(current_indent-1);
                            draggable.removeClass(before);
                            draggable.addClass(after);
                            dxoffset = evt.pageX - draggable.position().left;
                            hasChanged = true;
                        }
                    }
                }
            }
        }
    });
});

/**
 * taxonomy_add_child
 *
 * add a child of current term.
 */
function ChildAdder(term_id)
{
    this.term_id = term_id;
    var me=this;
    this.invoke=function() {
        taxonomy_add_child(me.term_id);
    }
}

function taxonomy_add_child(term_id)
{
    if (taxonomy_check_tree(new ChildAdder(term_id))) {
        return;
    }

    $('#term-name-input').val('');
    $('#term-description-input').val('');
    $('#taxonomy-add-popup-name-label').css('color','#666');
    $('#taxonomy-add-popup-name-error').hide();
    $('#taxonomy-add-overlay').show();
    $('#taxonomy-add-popup').show();
    $('#taxonomy-add-cancel').click(function(evt) {
        $('#taxonomy-add-overlay').hide();
        $('#taxonomy-add-popup').hide();
    });
    $('#taxonomy-add-submit').click(function(evt) {
        name = $('#term-name-input').val();
        if (name.length == 0) {
            $('#taxonomy-add-popup-name-label').css('color','red');
            $('#taxonomy-add-popup-name-error').show();
        } else {
            $.post(
                '/admin/taxonomy/add-child/',
                {
                    name:name,
                    description:$('#term-description-input').val(),
                    parent_id:term_id
                },
                function (data) {
                    if (data.success) {
                        location.reload(true);
                    } else {
                        alert(data.why);
                    }
                    $('#taxonomy-add-overlay').hide();
                    $('#taxonomy-add-popup').hide();
                },
                'json'
            );
        }
    });

    return false;
}

/**
 * taxonomy_detach
 *
 * make current term a root term.
 */
function Detacher(term_id)
{
    this.term_id = term_id;
    var me=this;
    this.invoke=function() {
        taxonomy_detach(me.term_id);
    }
}

function taxonomy_detach(term_id)
{
    if (taxonomy_check_tree(new Detacher(term_id))) {
        return;
    }

    if (confirm(detachMessage)) {
        $.post(
            '/admin/taxonomy/detach/',
            {
                term_id:term_id
            },
            function (data) {
                if (data.success) {
                    location.reload(true);
                } else {
                    alert(data.why);
                }
            },
            'json'
        );
    }
    return false;
}

/**
 * taxonomy_delete
 *
 * delete current term.
 */
function Deleter(term_id)
{
    this.term_id = term_id;
    var me=this;
    this.invoke=function() {
        taxonomy_delete(me.term_id);
    }
}

function taxonomy_delete(term_id)
{
    if (taxonomy_check_tree(Deleter(term_id))) {
        return;
    }

    if (confirm(deleteMessage)) {
        $.post(
            '/admin/taxonomy/delete/',
            {
                term_id:term_id
            },
            function (data) {
                if (data.success) {
                    location.reload(true);
                } else {
                    alert(data.why);
                }
            },
            'json'
        );
    }
    return false;
}

/**
 * taxonomy_add_child
 *
 * add a child of current term.
 */
function Attacher(term_id)
{
    this.term_id = term_id;
    var me=this;
    this.invoke=function() {
        taxonomy_attach_term(me.term_id);
    }
}

function taxonomy_attach_term(term_id)
{
    if (taxonomy_check_tree(new Attacher(term_id))) {
        return;
    }

    $('#taxonomy-add-overlay').show();
    $('#taxonomy-attach-popup').show();
    $('#taxonomy-attach-cancel').click(function(evt) {
        $('#taxonomy-add-overlay').hide();
        $('#taxonomy-attach-popup').hide();
    });
    $('#taxonomy-attach-submit').click(function(evt) {
        $.post(
            '/admin/taxonomy/attach/',
            {
                term_id:term_id,
                parent_id:$('#term-attachid-select').val()
            },
            function (data) {
                if (data.success) {
                    location.reload(true);
                } else {
                    alert(data.why);
                }
                $('#taxonomy-add-overlay').hide();
                $('#taxonomy-attach-popup').hide();
            },
            'json'
        );
    });

    return false;
}

/**
 * taxonomy_check_tree
 *
 * Ask the user if he wants to save the tree and returns true
 * if he choose to do so, false otherwise.
 */
function taxonomy_check_tree(cb)
{
    if (hasChanged) {
        if (confirm(checkMessage)) {
            taxonomy_save_tree(cb);
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }
}

/**
 * taxonomy_save_tree
 *
 * Save the current taxonomy tree
 */
function taxonomy_save_tree(cb)
{
    var idx = 0;
    var tree_ids = new Array();
    var tree_indents = new Array();
    $('.taxonomy-root').each(function () {
        tree_ids[idx] = this.id.replace('taxonomy-root-','');
        tree_indents[idx] = 0;
        ++idx;
        $('#'+this.id + ' .taxonomy-draggable').each(function () {
            tree_ids[idx] = this.id.replace('taxonomy-term-','');
            tree_indents[idx] = get_indent($(this));
            ++idx;
        });
    });

    $.post(
        '/admin/taxonomy/save-tree/',
        {tree_ids:tree_ids,tree_indents:tree_indents},
        function (data) {
            if (data.success) {
                hasChanged = false;
                if (cb == null) {
                    location.reload(true);
                } else {
                    cb.invoke();
                }
            } else {
                alert(data.why);
            }
        },
        'json'
    );

    return false;
}

